import { WSDL } from '@dct/soap';
import { OperationElement } from '@dct/soap/lib/wsdl/elements';
import * as _ from 'lodash';

const classTemplate = `import { createClient, Client,IOptions } from '@dct/soap';
{{models}}
export class {{className}} {
    private client: Client;
    constructor(private url: string,private options?: IOptions, private endpoint?: string) {
        
    }
    async init() {
        this.client = await createClientAsync(this.url, this.options, this.endpoint);
    }
    {{methods}}
}
`
const methodTemplate = _.template(`
    async {{methodName}}(params: {{InputType}}) : {{OutputType}} {
        return this.client.{{methodName}}(params);
    }
`)

function listMethods(wsdl: WSDL) :Array<[string, OperationElement]>{
   const services = wsdl.definitions.services
   let ret = []
   if(!_.isEmpty(services)) {
       // process bindings
     for(let sn in services) {
        const service = services[sn];
        const bindings = Object.values(service.ports).map((port) => port.binding);
        for(let binding of bindings) {
            const operations = Array.from(Object.entries(binding.methods))
            ret = ret.concat(operations);
        }
     }
   } else {
    const bindings = Object.values(wsdl.definitions.bindings);
    for(let binding of bindings) {
        const operations = Array.from(Object.entries(binding.methods))
        ret = ret.concat(operations);
    }
   }
   return ret;
}
function generateClassMethod(wsdl: WSDL, methodEntry: [string, OperationElement], typeSet:Array<any>) {
   const [methodName, method] = methodEntry;
   const input = method.input;
   const InputTypeSchema = wsdl.findSchemaObject(method.$targetNamespace, input.$type||input.$lookupType)
   typeSet.push(InputTypeSchema);
   const InputType = InputTypeSchema.$name;
   const output = method.output;
   const OutputTypeSchema = wsdl.findSchemaObject(method.$targetNamespace, output.$type||output.$lookupType)
   typeSet.push(OutputTypeSchema);
}

function generateClass(wsdl: WSDL, className: string) {
   
}